﻿/*******************************************************************
Copyright (c) 2011 이재범

*  Permission is hereby granted, free of charge, to any person
*  obtaining a copy of this software and associated documentation
*  files (the "Software"), to deal in the Software without
*  restriction, including without limitation the rights to use,
*  copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the
*  Software is furnished to do so, subject to the following
*  conditions:
* 
*  The above copyright notice and this permission notice shall be
*  included in all copies or substantial portions of the Software.
* 
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
*  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
*  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
*  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
*  OTHER DEALINGS IN THE SOFTWARE.
*******************************************************************/

#include "search.h"
#include <boost/filesystem.hpp>
#include <vector>
int Search::total_num_data = 0;
vector<Dictionary<string>*> Search::database;
vector<Dictionary<string>*> Search::equation_db;
vector<Dictionary<string>*> Search::equation_normal_db;

vector<string> file;
int count_file_num(string dir_path);

Search::Search(string& _query)
{
	num_result = 0;
	query = _query;
	Hash q(query);

	q.generate_hash_data();
	q.extract_searching_query(entire_hash, hash_operand, hash_operator, hash_det);

	bool result_num_overflow = false;
	for(int i = 0; i < total_num_data; i ++)
	{
		for(int j = 0; j < database[i]->size(); j ++)
		{
			if(num_result > 500)
			{
				result_num_overflow = true;
				break;
			}

			vector<int> occurence = bmp_search((*database[i])[j], entire_hash);

			// 찾았다면
			if(!occurence.empty())
			{
				cout << "Match found at " << j<< "th equation of " << file[i] << "th article " << endl;
				cout << (*equation_db[i])[j] << endl << endl;

				string result =  "equation of " + file[i] + "th article \n"  + (*equation_db[i])[j] + "\n" ;
				search_result.push_back(result);

				num_result ++;
			}
		}
	}

	// 검색 결과 개수가 너무 많으면 정확히 일치하는 것만을 뽑아 내야만 한다. 
	if(result_num_overflow)
	{

	}
}

void Search::load_database()
{
	cout << "DATABASE LOADING STARTED... " << endl;
	string dir_path = "D:\\equation_search\\search\\tex";

	int file_num = count_file_num(dir_path);
	boost::filesystem::path data_dir(dir_path);

	if(!boost::filesystem::is_directory(data_dir))
		return;

	boost::filesystem::directory_iterator end_itr;

	int cnt = 0;
	for(boost::filesystem::directory_iterator dir_itr(data_dir); dir_itr != end_itr; dir_itr ++, cnt++)
	{
		if(cnt % ( file_num / 20 ) == 0)
			cout << "=";

		if(boost::filesystem::is_regular_file(dir_itr->status()))
		{
			if(dir_itr->path().filename().string() != "result")
			{
				database.push_back(new Dictionary<string>(dir_itr->path().string()));
				file.push_back(dir_itr->path().filename().string());
				total_num_data++;
			}
		}
	}

	dir_path = "D:\\equation_search\\search\\tex\\original";
	boost::filesystem::path original_dir(dir_path);

	if(!boost::filesystem::is_directory(original_dir))
		return;

	cnt = 0;
	for(boost::filesystem::directory_iterator dir_itr(original_dir); dir_itr != end_itr; dir_itr ++, cnt ++)
	{
		if(cnt % ( file_num / 20 ) == 0)
			cout << "=";

		if(boost::filesystem::is_regular_file(dir_itr->status()))
		{	
			equation_db.push_back(new Dictionary<string>(dir_itr->path().string()));
		}
	}

	dir_path = "D:\\equation_search\\search\\tex\\normal";
	boost::filesystem::path normal_dir(dir_path);

	if(!boost::filesystem::is_directory(original_dir))
		return;

	cnt = 0;
	for(boost::filesystem::directory_iterator dir_itr(normal_dir); dir_itr != end_itr; dir_itr ++, cnt ++)
	{
		if(cnt % ( file_num / 20 ) == 0)
			cout << "=";

		if(boost::filesystem::is_regular_file(dir_itr->status()))
		{
			equation_normal_db.push_back(new Dictionary<string>(dir_itr->path().string()));
		}
	}
}
void Search::partial_search(string& _query)
{
	query = _query;
}
int count_file_num(string dir_path)
{
	boost::filesystem::path data_dir(dir_path);
	boost::filesystem::directory_iterator end_itr;

	int total_num = 0;
	for(boost::filesystem::directory_iterator dir_itr(data_dir); dir_itr != end_itr; dir_itr ++)
	{
		if(boost::filesystem::is_regular_file(dir_itr->status()))
		{
			total_num ++;
		}
	}

	return total_num;
}